home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / CH_5.6 / fitspline / fitspline.c next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  8.4 KB  |  266 lines

  1. /*
  2.  * fitspline.c
  3.  *
  4.  * Practical Algorithms for Image Analysis
  5.  *
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /* FITSPLINE:   program performs spline fit upon image lines, where
  10.  *            input is in PCC code, and where spline nodes have been
  11.  *              determined by polygonalization
  12.  *     usage: fitspline infile outimg [-t THRESHOLD] [-g GRANULARITY] [-i] [-L]
  13.  */
  14.  
  15. #define THRESH_DFLT 5
  16. #define GRAN_DFLT 5             /* granularity of pts between spline nodes */
  17.  
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include <stdlib.h>
  21. #include <images.h>
  22. #include <tiffimage.h>
  23. #include "pcc2.h"               /* for PCC programs */
  24. extern void print_sos_lic ();
  25.  
  26. unsigned char *fcCode;          /* code storage */
  27. long nByteCode;                 /* no. bytes in code storage */
  28.  
  29. long xytoline (struct point *, long *, long *, long *);
  30. long spline (struct point *, long, unsigned char **,
  31.              struct point, long, short);
  32. long usage (short);
  33. long input (int, char **, long *, long *, short *);
  34.  
  35.  
  36. main (argc, argv)
  37.      int argc;
  38.      char *argv[];
  39. {
  40.   Image *imgO;                  /* pointer to output image structure */
  41.   unsigned char **image;        /* output image array */
  42.   long width, height;           /* image size */
  43.   struct point imgSize;         /* image size */
  44.   long thresh;                  /* threshold for fit */
  45.   short splineType;             /* =1 for approx spline; or =2 for interp */
  46.   long gran;                    /* granularity of pts between spline nodes */
  47.   struct point *data;           /* data curve */
  48.   long nData;                   /* no. coords in data curve */
  49.   long nSegments;               /* number of segments found */
  50.   long nStructs;                /* number of line structures found */
  51.   long lengthSqr, area;         /* length sqr.ed and area of line fits */
  52.   long deltaX, deltaY;          /* x and y increments for line fits */
  53.   long iNode, nNodes;           /* index and number of spline node points */
  54.   struct point *nodes;          /* array of spline nodes for each structure */
  55.   struct point pt0;             /* points to connect fits between */
  56.   long x, y;
  57.   long i;
  58.  
  59. /* user input */
  60.   if (input (argc, argv, &thresh, &gran, &splineType) < 0)
  61.     return (-1);
  62.  
  63. /* open input PCC file */
  64.   if (pccread (argv[1], &fcCode, &nByteCode, &width, &height) == -1)
  65.     exit (1);
  66.   printf ("image size: %dx%d, PCC length = %d\n", width, height, nByteCode);
  67.   imgSize.x = width;
  68.   imgSize.y = height;
  69.  
  70. /* allocate space for data coordinate array */
  71.   if ((data = (struct point *)
  72.        calloc (nByteCode * MAXPERCODE, sizeof (long))) == NULL) {
  73.     printf ("FITSPLINE: not enough memory -- sorry");
  74.     return (-1);
  75.   }
  76.  
  77. /* construct tables of feature chain decodes */
  78.   pccdecodes ();
  79.  
  80. /* perform feature chain decoding */
  81.   pcc2xy (data, &nData);
  82.  
  83. /* re-allocate data memory */
  84.   data[nData++].x = -STOPCODE;
  85.   if ((data = (struct point *)
  86.        realloc (data, nData * sizeof (struct point))) == NULL) {
  87.     printf ("FITSPLINE: not enough memory -- sorry");
  88.     return (-2);
  89.   }
  90.  
  91. /* find x,y coordinates for each line */
  92.   if (xytoline (data, &nData, &nSegments, &nStructs) < 0)
  93.     return (-1);
  94.  
  95. /* allocate output image */
  96.   imgO = ImageAlloc (height, width, 8);
  97.   image = ImageGetPtr (imgO);
  98.  
  99. /* initialize image */
  100.   for (y = 0; y < height; y++)
  101.     for (x = 0; x < width; x++)
  102.       image[y][x] = 255;
  103.  
  104. /* allocate spline node memory */
  105.   if ((nodes = (struct point *)
  106.        calloc (nData, sizeof (struct point))) == NULL) {
  107.     printf ("FITSPLINE: not enough memory -- sorry");
  108.     return (-3);
  109.   }
  110.  
  111. /* determine polygonal fits */
  112.   for (i = 0, iNode = nNodes = 0; i < nData; i++) {
  113.     if (data[i].x != -1) {
  114.       nodes[iNode].x = data[i].x;
  115.       nodes[iNode++].y = data[i].y;
  116.       nodes[iNode].x = data[i].x;  /* replicate first point */
  117.       nodes[iNode++].y = data[i].y;
  118.       nNodes++;
  119.       pt0.x = data[i].x;
  120.       pt0.y = data[i].y;
  121.       i++;
  122.       if (data[i].x < 0) {      /* one pixel line */
  123.         image[nodes[iNode - 1].y][nodes[iNode - 1].x] = 255;
  124.         iNode = 0;
  125.         nNodes++;
  126.       }
  127.       else {
  128.         lengthSqr = area = 0;
  129.         while (data[i].x >= 0) {
  130.           x = data[i].x - pt0.x;
  131.           y = data[i].y - pt0.y;
  132.           deltaX = data[i].x - data[i - 1].x;
  133.           deltaY = data[i].y - data[i - 1].y;
  134.           lengthSqr += 2 * (x * deltaX + y * deltaY)
  135.             + deltaX * deltaX + deltaY * deltaY;
  136.           area += x * deltaY - y * deltaX;
  137.           if ((area * area) > (thresh * lengthSqr)) {
  138.             nodes[iNode].x = data[i].x;
  139.             nodes[iNode++].y = data[i].y;
  140.             nNodes++;
  141.             pt0.x = data[i].x;
  142.             pt0.y = data[i].y;
  143.             lengthSqr = area = 0;
  144.           }
  145.           i++;
  146.         }
  147.         if (lengthSqr > 0) {
  148.           nodes[iNode].x = data[i - 1].x;
  149.           nodes[iNode++].y = data[i - 1].y;
  150.           nNodes++;
  151.         }
  152.         nodes[iNode].x = data[i - 1].x;  /* replicate final point */
  153.         nodes[iNode++].y = data[i - 1].y;
  154.         spline (nodes, iNode, image, imgSize, gran, splineType);
  155.         iNode = 0;
  156.       }
  157.       --i;
  158.     }
  159.   }
  160.  
  161.   printf ("Number of spline nodes = %d.\n", nNodes);
  162.  
  163.  
  164. /* write image output file */
  165.   ImageOut (argv[2], imgO);
  166.  
  167.   return (0);
  168. }
  169.  
  170.  
  171.  
  172. /* USAGE:       function gives instructions on usage of program
  173.  *                    usage: usage (flag)
  174.  *              When flag is 1, the long message is given, 0 gives short.
  175.  */
  176.  
  177. long
  178. usage (flag)
  179.      short flag;                /* flag =1 for long message; =0 for short message */
  180. {
  181.  
  182. /* print short usage message or long */
  183.   printf ("USAGE: fitspline infile outimg [-t THRESHOLD] [-g GRANULARITY] [-i] [-L] ");
  184.   if (flag == 0)
  185.     return (-1);
  186.  
  187.   printf ("\nfitspline performs spline fitting to image\n");
  188.   printf ("lines to produce smooth curve approximations.\n\n");
  189.   printf ("ARGUMENTS:\n");
  190.   printf ("    infile: input filename (PCC)\n");
  191.   printf ("    outimg: output image filename (TIF)\n\n");
  192.   printf ("OPTIONS:\n");
  193.   printf ("      -t THRESH: threshold on error for spline node determination;\n");
  194.   printf ("                 nodes are found from polygonalization. (Dflt = %d).\n", THRESH_DFLT);
  195.   printf ("                 The smaller this threshold, the closer the\n");
  196.   printf ("                 approximation of the original data, but more spline\n");
  197.   printf ("                 line fits will be required.\n");
  198.   printf (" -g GRANULARITY: number of points between each spline node;\n");
  199.   printf ("                 the greater the number of points, the smoother the\n");
  200.   printf ("                 approximation. (default = %d)\n", GRAN_DFLT);
  201.   printf ("             -i: to perform interpolation fitting, that is\n");
  202.   printf ("                 the fit runs through node points; a B-spline is used.\n");
  203.   printf ("                 The default is NOT interpolation, instead it is an\n");
  204.   printf ("                 approximation spline; a cardinal spline is used.\n");
  205.   printf ("                 The approximation spline is yields a close fit, but one\n");
  206.   printf ("                 one that does not usually pass through the node points.\n");
  207.   printf ("                 The approximation spline appears smoother than the\n");
  208.   printf ("                 interpolation spline.\n");
  209.   printf ("             -L: print Software License for this module\n");
  210.  
  211.  
  212.   return (-1);
  213. }
  214.  
  215.  
  216. /* INPUT:       function reads input parameters
  217.  *                  usage: input (argc, argv, &thresh, &gran, &splineType)
  218.  */
  219.  
  220. #define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
  221.  
  222. long
  223. input (argc, argv, thresh, gran, splineType)
  224.      int argc;
  225.      char *argv[];
  226.      long *thresh;              /* threshold on polygonal fit */
  227.      long *gran;                /* granularity of spline pts between nodes */
  228.      short *splineType;         /* =1 for approximation spline; or =2 for
  229.                                  * * interpolation spline */
  230. {
  231.   long n;
  232.  
  233.   if (argc == 1)
  234.     USAGE_EXIT (1);
  235.   if (argc == 2)
  236.     USAGE_EXIT (0);
  237.  
  238.   *thresh = THRESH_DFLT;
  239.   *gran = GRAN_DFLT;
  240.   *splineType = 1;
  241.  
  242.   for (n = 3; n < argc; n++) {
  243.     if (strcmp (argv[n], "-t") == 0) {
  244.       if (++n == argc)
  245.         USAGE_EXIT (0);
  246.       *thresh = (long) atol (argv[n]);
  247.     }
  248.     else if (strcmp (argv[n], "-g") == 0) {
  249.       if (++n == argc)
  250.         USAGE_EXIT (0);
  251.       *gran = (long) atol (argv[n]);
  252.     }
  253.     else if (strcmp (argv[n], "-i") == 0)
  254.       *splineType = 2;
  255.     else if (strcmp (argv[n], "-L") == 0) {
  256.       print_sos_lic ();
  257.       exit (0);
  258.     }
  259.     else
  260.       USAGE_EXIT (0);
  261.   }
  262.  
  263.  
  264.   return (0);
  265. }
  266.